<?php
/**
 * Created by PhpStorm
 * User: 龍zero
 * Date: 2022-04-10
 * Time: 16:28
 */
declare(strict_types=1);

namespace App\Lib\Tools;


use App\Exception\ParameterException;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;


class Paginator
{
    private function getStartCount($count,$page){
        $count = intval($count);
        $start = intval($page);
        if ($start < 0 || $count <= 0){
            throw new ParameterException([
                'message' => '分页参数异常'
            ]);
        }
        $start = $start * $count;

        return [$start, $count];
    }

    public function page($query,$count,$page,$column=['*']){
        if(!$query instanceof Builder && !$query instanceof Model){
            throw new ParameterException([
                'message' => '分页对象异常'
            ]);
        }
        list($start,$count) = $this->getStartCount((int)$count,(int)$page);
        if($query instanceof Builder){
            $totalNums = $query->toBase()->getCountForPagination();
            if(is_array($column)){
                $collect = $query->offset($start)->limit($count)->get($column);
            }elseif(is_string($column)){
                $collect = $query->offset($start)->limit($count)->pluck($column);
            }else{
                throw new ParameterException([
                    'message' => '分页对象异常'
                ]);
            }
        }else{
            $totalNums = $query::toBase()->getCountForPagination();
            if(is_array($column)){
                $collect = $query::offset($start)->limit($count)->get($column);
            }elseif(is_string($column)){
                $collect = $query::offset($start)->limit($count)->pluck($column);
            }else{
                throw new ParameterException([
                    'message' => '分页对象异常'
                ]);
            }
        }

        $pageList = $collect->toArray();
        $result = [
            'total' => $totalNums,
            'items' => $pageList,
            'count' => (int)$count,
            'page' => (int)$page,
            'total_page' => ceil((int)$totalNums / (int)$count)
        ];
        return $result;
    }

}